{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "convinced-museum",
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "national-customer",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = tf.keras.Sequential()\n",
    "img_rows, img_cols, img_ch = 28, 28, 1\n",
    "input_shape = (img_rows, img_cols, img_ch)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "typical-collins",
   "metadata": {},
   "outputs": [],
   "source": [
    "num_classes = 10\n",
    "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()\n",
    "x_train, x_test = x_train / 255.0, x_test / 255.0\n",
    "\n",
    "x_train = x_train.reshape(x_train.shape[0], *input_shape)\n",
    "x_test = x_test.reshape(x_test.shape[0], *input_shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "bronze-planner",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "=================================================================\n",
      "Total params: 156\n",
      "Trainable params: 156\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# When using this layer as the first layer in a model,\n",
    "# provide the keyword argument input_shape\n",
    "# (tuple of integers, does not include the sample axis)\n",
    "model.add(tf.keras.layers.Conv2D(\n",
    "    filters=6, kernel_size=(5,5), strides=(1, 1), padding='same',\n",
    "    data_format=None, dilation_rate=(1, 1), groups=1, activation='relu',\n",
    "    use_bias=True, kernel_initializer='glorot_uniform',\n",
    "    bias_initializer='zeros', kernel_regularizer=None,\n",
    "    bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,\n",
    "    bias_constraint=None, input_shape = input_shape\n",
    "))\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "polished-skiing",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 14, 14, 6)         0         \n",
      "=================================================================\n",
      "Total params: 156\n",
      "Trainable params: 156\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.add(tf.keras.layers.MaxPool2D(\n",
    "    pool_size=(2, 2), strides=None, padding='valid', data_format=None\n",
    "))\n",
    "# pool_size strides padding data_format\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "unlikely-therapy",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 14, 14, 6)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 10, 10, 16)        2416      \n",
      "=================================================================\n",
      "Total params: 2,572\n",
      "Trainable params: 2,572\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.add(tf.keras.layers.Conv2D(\n",
    "    filters=16, kernel_size=(5,5), strides=(1, 1), padding='valid',\n",
    "    data_format=None, dilation_rate=(1, 1), groups=1, activation='relu',\n",
    "    use_bias=True, kernel_initializer='glorot_uniform',\n",
    "    bias_initializer='zeros', kernel_regularizer=None,\n",
    "    bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,\n",
    "    bias_constraint=None\n",
    "))\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "false-psychiatry",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 14, 14, 6)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 10, 10, 16)        2416      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 5, 5, 16)          0         \n",
      "=================================================================\n",
      "Total params: 2,572\n",
      "Trainable params: 2,572\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.add(tf.keras.layers.MaxPool2D(\n",
    "    pool_size=(2, 2)\n",
    "))\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "differential-angola",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 14, 14, 6)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 10, 10, 16)        2416      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 5, 5, 16)          0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 400)               0         \n",
      "=================================================================\n",
      "Total params: 2,572\n",
      "Trainable params: 2,572\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.add(tf.keras.layers.Flatten())\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "freelance-wayne",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 14, 14, 6)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 10, 10, 16)        2416      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 5, 5, 16)          0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 400)               0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 120)               48120     \n",
      "=================================================================\n",
      "Total params: 50,692\n",
      "Trainable params: 50,692\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.add(tf.keras.layers.Dense(120, activation='relu'))\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "enabling-spray",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 14, 14, 6)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 10, 10, 16)        2416      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 5, 5, 16)          0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 400)               0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 120)               48120     \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 120)               14520     \n",
      "=================================================================\n",
      "Total params: 65,212\n",
      "Trainable params: 65,212\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.add(tf.keras.layers.Dense(120, activation='relu'))\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "intended-somerset",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 14, 14, 6)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 10, 10, 16)        2416      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 5, 5, 16)          0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 400)               0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 120)               48120     \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 120)               14520     \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 10)                1210      \n",
      "=================================================================\n",
      "Total params: 66,422\n",
      "Trainable params: 66,422\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.add(tf.keras.layers.Dense(\n",
    "    num_classes, activation = 'softmax'\n",
    "))\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "military-atlanta",
   "metadata": {},
   "outputs": [],
   "source": [
    "callbacks = [\n",
    "    # Callback to interrupt the training if the validation loss (`val_loss`) stops improving for over 3 epochs:\n",
    "    tf.keras.callbacks.EarlyStopping(patience=5, monitor='val_loss'),\n",
    "    # Callback to log the graph, losses and metrics into TensorBoard (saving log files in `./logs` directory):\n",
    "    tf.keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=1, write_graph=True)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "sized-conservation",
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer='sgd', loss='sparse_categorical_crossentropy', metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "structural-missile",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/20\n",
      "   1/1875 [..............................] - ETA: 0s - loss: 2.2862 - accuracy: 0.1875WARNING:tensorflow:From D:\\Users\\10402\\anaconda3\\envs\\tensorflow\\lib\\site-packages\\tensorflow\\python\\ops\\summary_ops_v2.py:1277: stop (from tensorflow.python.eager.profiler) is deprecated and will be removed after 2020-07-01.\n",
      "Instructions for updating:\n",
      "use `tf.profiler.experimental.stop` instead.\n",
      "   2/1875 [..............................] - ETA: 7:58 - loss: 2.2881 - accuracy: 0.1562WARNING:tensorflow:Callbacks method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0110s vs `on_train_batch_begin` time: 0.0435s). Check your callbacks.\n",
      "WARNING:tensorflow:Callbacks method `on_train_batch_end` is slow compared to the batch time (batch time: 0.0110s vs `on_train_batch_end` time: 0.4248s). Check your callbacks.\n",
      "1875/1875 [==============================] - 13s 7ms/step - loss: 0.6047 - accuracy: 0.8062 - val_loss: 0.1469 - val_accuracy: 0.9552\n",
      "Epoch 2/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.1400 - accuracy: 0.9565 - val_loss: 0.0914 - val_accuracy: 0.9723\n",
      "Epoch 3/20\n",
      "1875/1875 [==============================] - 13s 7ms/step - loss: 0.0957 - accuracy: 0.9705 - val_loss: 0.0724 - val_accuracy: 0.9759\n",
      "Epoch 4/20\n",
      "1875/1875 [==============================] - 12s 7ms/step - loss: 0.0752 - accuracy: 0.9768 - val_loss: 0.0596 - val_accuracy: 0.9798\n",
      "Epoch 5/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0635 - accuracy: 0.9804 - val_loss: 0.0526 - val_accuracy: 0.9829\n",
      "Epoch 6/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0559 - accuracy: 0.9827 - val_loss: 0.0480 - val_accuracy: 0.9821\n",
      "Epoch 7/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0495 - accuracy: 0.9846 - val_loss: 0.0438 - val_accuracy: 0.9860\n",
      "Epoch 8/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0447 - accuracy: 0.9862 - val_loss: 0.0415 - val_accuracy: 0.9865\n",
      "Epoch 9/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0400 - accuracy: 0.9879 - val_loss: 0.0382 - val_accuracy: 0.9876\n",
      "Epoch 10/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0372 - accuracy: 0.9887 - val_loss: 0.0424 - val_accuracy: 0.9867\n",
      "Epoch 11/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0341 - accuracy: 0.9891 - val_loss: 0.0361 - val_accuracy: 0.9887\n",
      "Epoch 12/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0317 - accuracy: 0.9897 - val_loss: 0.0343 - val_accuracy: 0.9886\n",
      "Epoch 13/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0294 - accuracy: 0.9905 - val_loss: 0.0332 - val_accuracy: 0.9886\n",
      "Epoch 14/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0272 - accuracy: 0.9913 - val_loss: 0.0323 - val_accuracy: 0.9892\n",
      "Epoch 15/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0249 - accuracy: 0.9916 - val_loss: 0.0327 - val_accuracy: 0.9891\n",
      "Epoch 16/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0231 - accuracy: 0.9926 - val_loss: 0.0365 - val_accuracy: 0.9869\n",
      "Epoch 17/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0212 - accuracy: 0.9931 - val_loss: 0.0341 - val_accuracy: 0.9887\n",
      "Epoch 18/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0200 - accuracy: 0.9939 - val_loss: 0.0333 - val_accuracy: 0.9886\n",
      "Epoch 19/20\n",
      "1875/1875 [==============================] - 12s 6ms/step - loss: 0.0184 - accuracy: 0.9942 - val_loss: 0.0370 - val_accuracy: 0.9887\n"
     ]
    }
   ],
   "source": [
    "history = model.fit(x_train, y_train,\n",
    "                    batch_size=32, epochs=20, validation_data=(x_test, y_test), \n",
    "                    verbose=1,  # change to `verbose=1` to get a progress bar\n",
    "                                # (we opt for `verbose=2` here to reduce the log size)\n",
    "                    callbacks=callbacks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "nervous-prerequisite",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Save your model\n",
    "model.save('my_model.h5')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "compound-performer",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d (Conv2D)              (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "max_pooling2d (MaxPooling2D) (None, 14, 14, 6)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_1 (Conv2D)            (None, 10, 10, 16)        2416      \n",
      "_________________________________________________________________\n",
      "max_pooling2d_1 (MaxPooling2 (None, 5, 5, 16)          0         \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 400)               0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 120)               48120     \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 120)               14520     \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 10)                1210      \n",
      "=================================================================\n",
      "Total params: 66,422\n",
      "Trainable params: 66,422\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# Load your (or someone else's) model\n",
    "new_model = tf.keras.models.load_model('my_model.h5')\n",
    "\n",
    "new_model.summary()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
